// 这里存储的是在线用户表
// 因为账户要保存登录状态，给服务器和其他用户使用
// 用户重复登录
// 1-当新用户登录，老用户依然在线时
// 顶号，新的账号顶掉旧的账户，新的账号能够登录成功
// 不允许重复登录，新的账户不能登录成功
// 允许同时登录多个账户，比如一些视频软件
// 可以显示用户的在线状态
// 这个项目是仿qq的一个项目，那么qq好友在线的功能需要使用这个实现
const {
	OnlineUser,
	Message
} = require("../config/class.js")
const {
	getFriendIdsByEmailId
} = require("../db/friendsdb.js");

// 用于保存的map映射对象
// 所有登录成功的用户，会在这里进行保存，直到离线
const onlineUsers = new Map([
	// ['66ce74dd48e3a3cdc81e5779', new OnlineUser({
	// 	"_id": '66ce74dd48e3a3cdc81e5779'
	// })]
]);
// 等待重连池
const reconnectUsers = new Map();


// 增加用户的方法
let addUser = (userId, userInfo) => {
	onlineUsers.set(String(userId), userInfo);
}

// 删除用户的方法
let removeUser = (userId) => {
	// 通过id值，删除对应的用户消息
	onlineUsers.delete(String(userId));
}

// 获取用户的方法
let getUser = (userId) => {
	return onlineUsers.get(String(userId));
}

// 获取所有在线用户的方法
let getAllUsers = () => {
	return Array.from(onlineUsers.values());
}

// 判断用户在线状态
// 返回true时为在线，false时为离线
let isUserOnline = (userId) => {
	return onlineUsers.has(String(userId));
}


// 根据传入的好友id列表，提示用户的好友该用户的状态发生了改变
let hintOnlineState = (friendlist, userObj, State = true) => {
	friendlist.forEach((friendId) => {
		// 判断该好友是否在线
		if (isUserOnline(friendId)) {
			let friend = getUser(friendId);
			// 循环提示，用户上线信息
			if (friend.sokcet) {
				friend.sokcet.emit("HintOnline", userObj._id, userObj.username, State ? "在线" : "离线");
			}
		}
	});
}


// 标记用户离线重连
// 设置一个时间，当一段时间内没有重新连接，就清除用户在线状态，停止维护用户表
let outTime = 1000 * 60 * 1;
let reconnectState = async (userObj, callback) => {
	// 重新标记映射中的状态值为重连    
	let user = getUser(userObj._id);
	user.state = 0;
	addUser(userObj._id, user);

	// 这里设置的是清除的时间    
	let Thread = setTimeout(async () => {
		// 删除指定id的用户连接    
		console.log("清除用户的连接痕迹");

		try {
			// 1-获取好友列表，并且提示其他用户
			let friendlist = await getFriendIdsByEmailId(userObj.friendId);
			hintOnlineState(friendlist.data, userObj, false);
		} catch (error) {
			console.error("在获取好友列表或通知在线好友时发生错误:", error);
		}

		removeUser(userObj._id);
		// 使用回调函数    
		callback();
	}, outTime);


	reconnectUsers.set(userObj._id, Thread);

	return Thread;
};

// 重连
// 重连方法就将setTimeout的计时器清除
let reconnect = (userId) => {
	// 获取连接对象
	let Thread = reconnectUsers.get(userId)
	if (Thread) {
		// 清除离线倒计时
		clearTimeout(Thread);
		reconnectUsers.delete(userId);
	}
}


module.exports = {
	onlineUsers, //获取在线列表的方法
	addUser, // 增加用户的方法
	removeUser, // 删除用户的方法
	getUser, // 获取用户的方法
	getAllUsers, // 获取所有在线用户的方法
	isUserOnline, // 判断用户在线状态
	reconnectState, //设置用户重连状态
	reconnect, //用户重连
	hintOnlineState, //根据传入的好友id列表，提示用户的好友该用户的状态发生了改变
};